﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using Battleship_569.Data;

namespace Battleship_569
{
    public partial class Game : Form
    {

        private BattleGridManager playerGrid = new BattleGridManager(); // Create new Grid
        private static bool isFailconnect = false;

        private BattleGridManager player1_Grid = new BattleGridManager(); // Create my Grid
        private BattleGridManager player2_Grid = new BattleGridManager(); // Create guest Grid


        private const int row = 15,
                          col = 15,
                          left = 20,
                          up = 20,
                          size = 20,
                          right = col*size + left,
                          down = up + row*size;

        private static bool connection = false; // kiem tra da ket noi hay chua.
        private int player = 1; //1 - nguoi choi 1, 2 - nguoi choi 2.
        private List<Point> listUndo = new List<Point>(); // danh sach thuyen cua nguoi choi
        private List<Battleship> listPlayer1Ships = new List<Battleship>(); // TinNT - List my ships

        private List<Battleship> listPlayer2Ships = new List<Battleship>();
                                 // TinNT - Receive Player 2's ships through network

        private int numBoatPlayer1 = 10; // tong so thuyen Player 1.
        private int numBoatPlayer2 = 10; // tong so thuyen Player 2.
        private int numSmallShip = 3; // so thuyen 1 o
        private int numNormalShip = 3; // so thuyen 2 o
        public int[,] BoardArr = new int[15,15]; // toa do co thuyen
        private int typeBoat = 1; // loai thuyen
        private bool exactly = true; // kiem tra xem ban trung hay khong; Nhan tu` nguoi choi khac.
        private bool endgame = false; // kiem tra xem ket thuc game hay chua; Nhan tu nguoi choi khac
        private int _X = -1; // toa do X ben minh bi ban
        private int _Y = -1; // toa do Y ben minh bi ban
        private bool _Exactly = true; // ban trung đối phương
        private bool _Endgame = false; // đối phuong thua
        private bool ready = false; // da dat thuyen xong; Nhan tu nguoi choi khac.
        private Image normal = new Bitmap(Properties.Resources.boat);
        private Image big = new Bitmap(Properties.Resources.boatbig);
        private Image bigdoc = new Bitmap(Properties.Resources.boatbigdoc);
        private Image miss = new Bitmap(Properties.Resources.miss);
        private Image destroy = new Bitmap(Properties.Resources.destroy);
        private Image thuyen3o = new Bitmap(Properties.Resources.thuyen3o);
        private Image thuyen3odoc = new Bitmap(Properties.Resources.thuyen3odoc);
        private Graphics graph;

        public Game()
        {
            InitializeComponent();


        }

        #region code cua Dienml

        private void TaoBien()
        {
            Width = 1050;
            Height = 470;
            if (!connection)
            {
                panel2.Visible = false;
            }
            else
            {
                panel2.Visible = true;
            }
        }

        private void panel1_Paint(object sender, PaintEventArgs e)
        {
            graph = e.Graphics;
            Pen pen = new Pen(Color.Yellow);
            for (int i = 0; i < 16; i++)
            {
                graph.DrawLine(pen, left, size*(i + 1), right, size*(i + 1));
                graph.DrawLine(pen, size*(i + 1), up, size*(i + 1), down);
            }
        }

        private void panel2_Paint(object sender, PaintEventArgs e)
        {
            graph = e.Graphics;
            Pen pen = new Pen(Color.Yellow);
            for (int i = 0; i < 16; i++)
            {
                graph.DrawLine(pen, left, size*(i + 1), right, size*(i + 1));
                graph.DrawLine(pen, size*(i + 1), up, size*(i + 1), down);
            }

        }

        // TinNT - Button Ready **********************************
        private void button1_Click(object sender, EventArgs e)
        {
            //if (numBoatPlayer1 == 0 && numBoatPlayer2 == 0)
            //{
            //    connection = true;
            //    TaoBien();
            //    beginProcess();
            //}
            //else
            //{
            //    connection = false;
            //}
            if(!Global.isCreateGame)
            {
                player = 1;
                string result = TCP.ReceiveData();
                if (result.Equals("Ok")) ready = true;
                TCP.SendData("Ok");
                string receivedata = TCP.ReceiveData();
                _X = int.Parse(receivedata.Split(',')[0]);
                _Y = int.Parse(receivedata.Split(',')[1]);
            }
            else
            {
                TCP.SendData("Ok");
                string result = TCP.ReceiveData();
                if (result.Equals("Ok")) ready = true;
            }
            
        }

        private void Game_Load(object sender, EventArgs e)
        {
            TaoBien();
            if(Global.isCreateGame)
            {
                player = 1;
                player1.Text = "Player 1";      
            } else
            {
                player = 2;
                player1.Text = "Player 2";
                player2.Text = "Player 1";
            }
            player1.Visible = true;
            player2.Visible = false;
            timer1.Interval = 500;
            timer1.Enabled = true;
            tmrWaitforready.Interval = 1000;
            timer2.Enabled = true;

        }

        // dat thuyen
        private void panel1_MouseClick(object sender, MouseEventArgs e)
        {
            if (e.X >= left && e.X <= right && e.Y >= up && e.Y <= down && numBoatPlayer1 != 0)
            {
                graph = panel1.CreateGraphics();
                int x = e.X/size - 1;
                int y = e.Y/size - 1;
                if (BoardArr[x, y] == 0) // vi tri nay chua co thuyen
                {
                    if (typeBoat == 1 && numSmallShip != 0)
                    {
                        listUndo.Add(new Point(x, y));
                        listPlayer1Ships.Add(new Battleship(1, 1, x, y, null));
                        BoardArr[x, y] = 1;
                        Pen p = new Pen(Color.Blue, 4f);
                        graph.DrawImage(normal, new Point((x + 1)*size, (y + 1)*size));
                        numBoatPlayer1 -= 1;
                        numSmallShip -= 1;
                    }
                    else if (e.X + 21 <= right && BoardArr[x + 1, y] == 0 && typeBoat == 2 && numNormalShip != 0)
                        // xet toa do de thuyen khong trung len nhau
                    {

                        BoardArr[x, y] = 1;
                        BoardArr[x + 1, y] = 1;
                        listPlayer1Ships.Add(new Battleship(2, 2, x, y, "across"));
                        listUndo.Add(new Point(x, y));
                        listUndo.Add(new Point(x + 1, y));
                        Pen p = new Pen(Color.Blue, 4f);
                        graph.DrawImage(big, new Point((x + 1)*size, (y + 1)*size));
                        numBoatPlayer1 -= 1;
                        numNormalShip -= 1;
                    }
                    else if (BoardArr[x, y + 1] == 0 && e.Y + 21 <= 320 && typeBoat == 3 && numNormalShip != 0)
                        // thuyen 2 o doc.
                    {
                        BoardArr[x, y] = 1;
                        BoardArr[x, y + 1] = 1;
                        listUndo.Add(new Point(x, y));
                        listPlayer1Ships.Add(new Battleship(3, 2, x, y, "down"));
                        listUndo.Add(new Point(x, y + 1));
                        Pen p = new Pen(Color.Blue, 4f);
                        graph.DrawImage(bigdoc, new Point((x + 1)*size, (y + 1)*size));
                        numBoatPlayer1 -= 1;
                        numNormalShip -= 1;
                    }
                    else if (typeBoat == 4 && e.X + 41 <= right && BoardArr[x + 1, y] == 0 && BoardArr[x + 2, y] == 0)
                        // thuyen 3 o ngang
                    {
                        BoardArr[x, y] = 1;
                        BoardArr[x + 1, y] = 1;
                        BoardArr[x + 2, y] = 1;
                        listPlayer1Ships.Add(new Battleship(4, 3, x, y, "across"));
                        listUndo.Add(new Point(x, y));
                        listUndo.Add(new Point(x + 1, y));
                        listUndo.Add(new Point(x + 2, y));
                        Pen p = new Pen(Color.Blue, 4f);
                        graph.DrawImage(thuyen3o, new Point((x + 1)*size, (y + 1)*size));
                        numBoatPlayer1 -= 1;
                    }
                    else if (typeBoat == 5 && BoardArr[x, y + 1] == 0 && BoardArr[x, y + 2] == 0 &&
                             e.Y + 41 <= 320 && typeBoat == 5) // thuyen 3 o doc
                    {
                        BoardArr[x, y] = 1;
                        BoardArr[x, y + 1] = 1;
                        BoardArr[x, y + 2] = 1;
                        listPlayer1Ships.Add(new Battleship(5, 3, x, y, "down"));
                        listUndo.Add(new Point(x, y));
                        listUndo.Add(new Point(x, y + 1));
                        listUndo.Add(new Point(x, y + 2));
                        Pen p = new Pen(Color.Blue, 4f);
                        graph.DrawImage(thuyen3odoc, new Point((x + 1)*size, (y + 1)*size));
                        numBoatPlayer1 -= 1;
                    }
                    if(numBoatPlayer1==0)
                    {
                        btn_Ready.Enabled = true;
                        button4.Enabled = false;
                        button5.Enabled = false;
                        ShipTwo.Enabled = false;
                        button7.Enabled = false;
                        button8.Enabled = false;
                    }
                }
            }
        }

        // ban thuyen doi phuong
        private void panel2_MouseClick(object sender, MouseEventArgs e)
        {
            if (!ready)
            {
                MessageBox.Show("Người chơi 2 chưa đặt tàu xong !!!");
            }
            else if (e.X >= left && e.X <= right && e.Y >= up && e.Y <= down&& !_Endgame)
            {
                graph = panel2.CreateGraphics();
                // den luot moi duoc di
                if (Global.isCreateGame&& player == 1) // kiem tra xem co phai luot nguoi choi 1 hay khong
                {
                    int x = e.X / size - 1; // vi tri ban
                    int y = e.Y / size - 1; // vi tri ban
                    /* 
                     * xu ly x, y o day roi tra ve ket qua
                     */
        
                        
                    if (_Exactly) // kiem tra ban trung hay khong
                    {
                        Pen p = new Pen(Color.Blue, 4f);
                        graph.DrawImage(destroy, new Point((x + 1) * size, (y + 1) * size));
                        // numBoat -= 1;
                        //  tin mat l kiem tra xem endgame chua roi tra ve bien bool nay cho tao
                        if (_Endgame)
                        {
                            MessageBox.Show("You win!!");
                            return;
                        }
                        player = 2;
                        player2.Visible = true;
                        player1.Visible = false;
                    }
                    else
                    {
                        Pen p = new Pen(Color.Blue, 4f);
                        graph.DrawImage(miss, new Point((x + 1) * size, (y + 1) * size));
                        player = 2;
                        player2.Visible = true;
                        player1.Visible = false;
                    }
                    //gui toa do ban
                    TCP.SendData(locateFire(x, y));
                    //    player = 2;
                    //nhan toa do ban
                    string receivedata = TCP.ReceiveData();
                    _X = int.Parse(receivedata.Split(',')[0]);
                    _Y = int.Parse(receivedata.Split(',')[1]);
                } else if(!Global.isCreateGame&&player==2) //  kiem tra luot nguoi choi 2
                {
                    int x = e.X / size - 1; // vi tri ban
                    int y = e.Y / size - 1; // vi tri ban
                    /* 
                     * xu ly x, y o day roi tra ve ket qua
                     */
                    
                    if (_Exactly) // kiem tra ban trung hay khong
                    {
                        Pen p = new Pen(Color.Blue, 4f);
                        graph.DrawImage(destroy, new Point((x + 1) * size, (y + 1) * size));
                        //  tin mat l kiem tra xem endgame chua roi tra ve bien bool nay cho tao
                        if (_Endgame)
                        {
                            MessageBox.Show("You win!!");
                            return;
                        }
                        player = 1;
                        player2.Visible = false;
                        player1.Visible = true;
                    }
                    else
                    {
                        Pen p = new Pen(Color.Blue, 4f);
                        graph.DrawImage(miss, new Point((x + 1) * size, (y + 1) * size));
                        player = 1;
                        player2.Visible = false;
                        player1.Visible = true;
                    }
                    TCP.SendData(locateFire(x, y));
                    //player = 2;
                    string receivedata = TCP.ReceiveData();
                    _X = int.Parse(receivedata.Split(',')[0]);
                    _Y = int.Parse(receivedata.Split(',')[1]);
                }
                
            }
        }        

        // Endgame
        private void checkEnd(int x, int y)
        {
            int check = 0;
            BoardArr[x, y] = 0;
            for (int i = 0; i < 15; i++)
            {
                for (int j = 0; j < 15; j++)
                {
                    check += BoardArr[i,j];
                }
            }
            if(check==0)
            {
                endgame = true;
            } else
            {
                endgame =  false;
            }
        }
        #endregion

        #region TinNT60491 - Khu vực của Tín đẹp zai :v
        // TinNT60491 - kiểm tra xem mình có bị bắn trúng không
        public bool isHit(int x, int y)
        {
            // 2 biến x,y là tọa độ nhận về từ bên Player 2 bắn qua bên Player 1
            if (BoardArr[x,y] != 0)
            {
                return true;
            }

            return false;
        }

        // nhận tọa độ đối phương bắn về phía mình
        // gán tọa độ đó vào _X _Y
        public void splitPoint(string strPoint)
        {
            List<string> listPoint = strPoint.Split(',').ToList();
            _X = int.Parse(listPoint[0]);
            _Y = int.Parse(listPoint[1]);
        }

        // nhận kết quả từ đối phương xem mình có bắn trúng hay không
        // có EndGame chưa - exactly,endgame
        public void splitResult(string strResult)
        {
            List<string> listResult = strResult.Split(',').ToList();

            this._Exactly = bool.Parse(listResult[0]);
            this._Endgame = bool.Parse(listResult[1]);
        }

        // tọa độ mình bắn đc sẽ gửi đi - string
        public string locateFire(int x, int y)
        {
            return x.ToString()+","+y.ToString();
        }

        // gửi kết quả đối phương bắn về phía mình
        // cho đối phương biết là có bắn trúng hay không
        // True / False => string (viết hoa chữ đầu)
        public string resultIsHit(bool exactly, bool endGame)
        {
            return exactly.ToString()+","+endGame.ToString();
        }
        #endregion


        private void Connect()
        {
            if (Global.isCreateGame)
            {
                Thread t = new Thread(threadWatingforClient);
                t.Start();
                //   Thread create = new Thread(CreateServer);
                //   create.Start();
                ////   SendData("Connect");
                //   string receive = ReceiveData();
                //   if (receive.Equals("Connected"))
                //   {
                //       connection = true;
                //       panel2.Visible = true;
                //   }
            }
            else
            {
                if (TCP.Client())
                {
                    connection = true;
                    panel2.Visible = true;
                }
                else
                {
                    isFailconnect = true;
                    MessageBox.Show("Cannot connect! Please try again!");
                    Form1 form1 = new Form1();
                    form1.Show();
                    this.Close();
                }
                //    connection = true;
                //    panel2.Visible = true;
                //    string rece = ReceiveData();
                //    if(rece=="Connect")
                //    {
                //        SendData("Connected");
                //    }
                //    //                  SendData("Connected");
                //    // TaoBien();

            }
        }

        //public void Server()
        //{
        //    ASCIIEncoding encoding = new ASCIIEncoding();
        //    IPAddress add = IPAddress.Any;
        //    TcpListener listener = new TcpListener(add, 8080);
        //    listener.Start();
        //    Socket socket = listener.AcceptSocket();

        //    //Socket socketSever = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        //    //IPEndPoint ipEndPoint = new IPEndPoint(add, 8080);

        //    //socketSever.Bind(ipEndPoint);

        //    //socketSever.Listen(1);

        //    //Socket socketClient = socketSever.Accept();

        //    // 2. receive
        //    byte[] data = new byte[1024];
        //    socket.Receive(data);
        //    string result = encoding.GetString(data);

        //    if (result.Equals("Connected"))
        //    {
        //        connection = true;
        //        panel2.Visible = true;

        //    }
        //    //return false;
        //}

        //public static bool Client()
        //{
        //    try
        //    {
        //        ASCIIEncoding encoding = new ASCIIEncoding();
        //        TcpClient client = new TcpClient();
        //        client.Connect("192.168.1.101", 8080);
        //        Stream stream = client.GetStream();
        //        // Socket socketClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        //        // IPEndPoint ipEndPoint = new IPEndPoint(IPAddress.Parse("192.168.1.101"), 8080);
        //        // socketClient.Connect(ipEndPoint);
        //        // // nhan du lieu 
        //        // byte[] dataArr = new byte[1024];
        //        //// int length = socketClient.Receive(dataArr);

        //        // // convert ve string 
        //        string s = "Connected";
        //        byte[] data = encoding.GetBytes(s);
        //        stream.Write(data, 0, data.Length);
        //        //dataArr = Encoding.ASCII.GetBytes(data);
        //        //socketClient.Send(dataArr, data.Length, SocketFlags.None);
        //        return true;
        //    }
        //    catch (Exception)
        //    {

        //        return false;
        //    }


        //}

        //public static void CreateServer()
        //{

        //    IPAddress address = IPAddress.Any;
        //    Global.SocketServer = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        //    IPEndPoint ipEndPoint = new IPEndPoint(address, 8080);

        //    Global.SocketServer.Bind(ipEndPoint);
        //    //chi cho 1 người ket noi vao 
        //    Global.SocketServer.Listen(1);

        //    Global.SocketClientofServer = Global.SocketServer.Accept();

        //    string senddata = "Connect";
        //    byte[] data = new byte[1024];
        //    data = Encoding.ASCII.GetBytes(senddata);
        //    Global.SocketClientofServer.Send(data, data.Length, SocketFlags.None);
        //}

        //public static bool JoinGame()
        //{
        //    try
        //    {
        //        Global.SocketClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        //        IPEndPoint ipEndPoint = new IPEndPoint(IPAddress.Parse(Global.HostIP), 8080);
        //        Global.SocketClient.Connect(ipEndPoint);
        //        return true;
        //    }
        //    catch (SocketException ex)
        //    {
        //        MessageBox.Show(ex.ToString());
        //    }
        //    return false;
        //}

       

        private void Game_FormClosing(object sender, FormClosingEventArgs e)
        {
            //Global.SocketClient.Shutdown(SocketShutdown.Both);
            //Global.SocketClient.Close();
            //Global.SocketClientofServer.Shutdown(SocketShutdown.Both);
            //Global.SocketClientofServer.Close();
            //Global.SocketServer.Close();


        }

        #region Button

        private void button4_Click(object sender, EventArgs e)
        {
            // Length = 1;
            typeBoat = 1;
        }



        private void button5_Click(object sender, EventArgs e)
        {
            button9.Visible = true;
            typeBoat = 2;
        }

        private void button6_Click(object sender, EventArgs e)
        {
            // Length = 2 doc;
            typeBoat = 3;
        }

        private void button7_Click(object sender, EventArgs e)
        {
            button9.Visible = true;
            typeBoat = 4;
        }

        private void button8_Click(object sender, EventArgs e)
        {
            // Length = 3 doc;
            typeBoat = 5;
        }

        private void btn_Quit_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }

        private void button3_MouseHover(object sender, EventArgs e)
        {
            button3.BackgroundImage = new Bitmap(Properties.Resources.newgamebut2);
        }

        private void button3_MouseLeave(object sender, EventArgs e)
        {
            button3.BackgroundImage = new Bitmap(Properties.Resources.newgamebut);
        }

        private void button2_MouseHover(object sender, EventArgs e)
        {
            btn_Quit.BackgroundImage = new Bitmap(Properties.Resources.quitbut2);
        }

        private void button2_MouseLeave(object sender, EventArgs e)
        {
            btn_Quit.BackgroundImage = new Bitmap(Properties.Resources.quitbut);
        }

        // button de xoay chieu thuyen
        private void button9_Click(object sender, EventArgs e)
        {
            if (typeBoat == 2)
            {
                button5.Visible = false;
                ShipTwo.Visible = true;
                typeBoat = 3;
            }
            else if (typeBoat == 3)
            {
                button5.Visible = true;
                ShipTwo.Visible = false;
                typeBoat = 2;
            }
            else if (typeBoat == 4)
            {
                button7.Visible = false;
                button8.Visible = true;
                typeBoat = 5;
            }
            else if (typeBoat == 5)
            {
                button7.Visible = true;
                button8.Visible = false;
                typeBoat = 4;
            }
        }

        #endregion

        private void timer1_Tick(object sender, EventArgs e)
        {
            timer1.Enabled = false;
            Connect();
        }

        private void timer2_Tick(object sender, EventArgs e)
        {
            if (_X >= 0 && _Y >= 0)
            {
                exactly = isHit(_X, _Y);
                if (Global.isCreateGame)
                {
                    player = 1;
                }
                else
                {
                    player = 2;
                }
                graph = panel1.CreateGraphics();
                Pen p = new Pen(Color.Blue, 4f);
                if (exactly)
                {
                    BoardArr[_X, _Y] = 0;
                    checkEnd(_X, _Y);
                    if(endgame)
                    {
                        MessageBox.Show("You Lose!!!");
                    }
                    graph.DrawImage(destroy, new Point((_X + 1)*size, (_Y + 1)*size)); 
                    _X = -1;
                    _Y = -1;
                }
                else
                {
                    graph.DrawImage(miss, new Point((_X + 1)*size, (_Y + 1)*size));
                    _X = -1;
                    _Y = -1;
                }
            }
        }

        public void threadWatingforClient()
        {
            if (TCP.Server())
            {
                connection = true;
                panel2.Visible = true;
                tmrWaitforready.Enabled = true;
            }
        }
        //NamDH - 
        private void tmrWaitforready_Tick(object sender, EventArgs e)
        {
            //Thread t = new Thread(threadWaitforReady);
            //t.Start();

        }
        //public void threadWaitforReady()
        //{
        //    string result = TCP.ReceiveData();
        //    if (result.Equals("Ok"))
        //    {
        //        ready = true;
        //        tmrWaitforready.Enabled = false;
        //    }
        //}
    }
}


